//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

package short_note_dao

import (
	"context"
	"fmt"
	"time"

	"atomgit.com/openlinksaas-org/api-server/dao/db_ns"
	"atomgit.com/openlinksaas-org/proto-gen-go.git/short_note_api"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
)

type ShortNoteDbItem struct {
	ShortNoteId   string `bson:"_id"`
	UserId        string `bson:"userId"`
	ProjectId     string `bson:"projectId"`
	ShortNoteType uint32 `bson:"shortNoteType"`
	TargetId      string `bson:"targetId"`
	TimeStamp     int64  `bson:"timeStamp"`
}

func (item *ShortNoteDbItem) ToShortNote(title, projectName string) *short_note_api.ShortNote {
	return &short_note_api.ShortNote{
		ProjectId:     item.ProjectId,
		ShortNoteType: short_note_api.SHORT_NOTE_TYPE(item.ShortNoteType),
		TargetId:      item.TargetId,
		Title:         title,
		TimeStamp:     item.TimeStamp,
		ProjectName:   projectName,
		MemberUserId:  item.UserId,
	}
}

type _ShortNoteDao struct {
	mc *mongo.Collection
}

func newShortNoteDao(db *mongo.Database) (*_ShortNoteDao, error) {
	mc := db.Collection(db_ns.DB_NS_SHORT_NOTE + "info")
	_, err := mc.Indexes().CreateOne(context.Background(), mongo.IndexModel{
		Keys: bson.D{{"userId", 1}, {"projectId", 1}},
	})
	if err != nil {
		return nil, err
	}
	return &_ShortNoteDao{mc: mc}, nil
}

func (db *_ShortNoteDao) Insert(ctx context.Context, dbItem *ShortNoteDbItem) error {
	if dbItem.TimeStamp == 0 {
		dbItem.TimeStamp = time.Now().UnixNano() / 1e6
	}
	dbItem.ShortNoteId = db.genShortNoteId(dbItem.UserId, dbItem.ProjectId, dbItem.ShortNoteType, dbItem.TargetId)
	_, err := db.mc.InsertOne(ctx, dbItem)
	return err
}

func (db *_ShortNoteDao) genShortNoteId(userId, projectId string, shortNoteType uint32, targetId string) string {
	return fmt.Sprintf("%s:%s:%d:%s", userId, projectId, shortNoteType, targetId)
}

func (db *_ShortNoteDao) Exist(ctx context.Context, userId, projectId string, shortNoteType uint32, targetId string) (bool, error) {
	shortNoteId := db.genShortNoteId(userId, projectId, shortNoteType, targetId)
	count, err := db.mc.CountDocuments(ctx, bson.M{"_id": shortNoteId, "userId": userId, "projectId": projectId})
	return count > 0, err
}
func (db *_ShortNoteDao) List(ctx context.Context, userIdList, projectIdList []string) ([]*ShortNoteDbItem, error) {
	cursor, err := db.mc.Find(ctx, bson.M{"userId": bson.M{"$in": userIdList}, "projectId": bson.M{"$in": projectIdList}})
	if err != nil {
		return nil, err
	}
	retList := []*ShortNoteDbItem{}
	err = cursor.All(ctx, &retList)
	return retList, err
}

func (db *_ShortNoteDao) RemoveByProject(ctx context.Context, userId, projectId string) error {
	_, err := db.mc.DeleteMany(ctx, bson.M{"userId": userId, "projectId": projectId})
	return err
}

func (db *_ShortNoteDao) Remove(ctx context.Context, userId, projectId string, shortNoteType uint32, targetId string) error {
	shortNoteId := db.genShortNoteId(userId, projectId, shortNoteType, targetId)
	_, err := db.mc.DeleteOne(ctx, bson.M{"_id": shortNoteId, "userId": userId, "projectId": projectId})
	return err
}
